package org.huawei260.String;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * @author Fql18
 * @Auther: qingle
 * @Date: 2024/8/25-0:33
 * @Description:
 *
 * 已经火星人使用的运算符号为# $
 * 其与地球人的等价公式如下
 * x#y=2*x+3*y+4
 * x$y=3*x+y+2
 * x y是无符号整数
 * 地球人公式按照c语言规则进行计算
 * 火星人公式中$符优先级高于#相同的运算符按从左到右的顺序运算
 *
 * 输入描述
 * 火星人字符串表达式结尾不带回车换行
 * 输入的字符串说明是 字符串为仅有无符号整数和操作符组成的计算表达式
 *
 * 用例保证字符串中操作数与操作符之间没有任何分隔符
 * 用例保证操作数取值范围为32位无符号整数，
 * 保证输入以及计算结果不会出现整型溢出
 * 保证输入的字符串为合法的求值报文
 * 例如: 123#4$5#76$78
 * 保证不会出现非法的求值报文
 * 例如:
 * #4$5 这种缺少操作数
 * 4$5# 这种缺少操作数
 * 4#$5 这种缺少操作数
 * 4 $5 有空格
 * 3+4-5*6/7 有其他操作符
 * 12345678987654321$54321 32位整数溢出
 *
 * @version: 1.0
 */
public class O0044_火星文计算_AI_OK_function {
				public static void main(String[] args) {
					Scanner scanner = new Scanner(System.in);
					String expression = scanner.nextLine(); // 读取输入的火星文表达式
					int result = evaluate(expression); // 计算表达式的值
					System.out.println(result); // 输出计算结果
					scanner.close();
				}

				private static int evaluate(String expression) {
					// 初始化操作符优先级
					Map<Character, Integer> precedence = new HashMap<>();
					precedence.put('#', 1);
					precedence.put('$', 2);

					// 使用栈来处理操作数和操作符
					Deque<Integer> nums = new ArrayDeque<>();
					Deque<Character> ops = new ArrayDeque<>();

					// 解析表达式，提取操作数和操作符
					tokenize(expression, nums, ops);
					// 根据操作符优先级计算表达式
					applyOperators(ops, nums, precedence);

					return nums.pop(); // 返回最终结果
				}

				// 解析表达式，提取操作数和操作符
				private static void tokenize(String expression, Deque<Integer> nums, Deque<Character> ops) {
					for (int i = 0; i < expression.length(); ) {
						char c = expression.charAt(i);
						if (Character.isDigit(c)) {
							// 如果字符是数字，解析整个数字并压入操作数栈
							int num = parseNumber(expression, i);
							nums.push(num);
							i += Character.digit(c, 10); // 移动到下一个字符
						} else if (c == '#' || c == '$') {
							// 如果字符是操作符，压入操作符栈
							ops.push(c);
							i++;
						} else {
							// 跳过无效字符
							i++;
						}
					}
				}

				// 从指定索引开始解析数字，直到遇到非数字字符
				private static int parseNumber(String expression, int index) {
					int num = 0;
					while (index < expression.length() && Character.isDigit(expression.charAt(index))) {
						num = num * 10 + (expression.charAt(index) - '0');
						index++;
					}
					return num;
				}

				// 根据操作符优先级计算表达式
				private static void applyOperators(Deque<Character> ops, Deque<Integer> nums, Map<Character, Integer> precedence) {
					while (!ops.isEmpty()) {
						char op = ops.pop();
						while (!ops.isEmpty() && precedence.get(ops.peek()) >= precedence.get(op)) {
							// 根据优先级计算操作符，并将结果压入操作数栈
							int b = nums.pop();
							int a = nums.pop();
							char currentOp = ops.pop();
							nums.push(calculate(a, b, currentOp));
						}
						// 计算当前操作符，并将结果压入操作数栈
						if (!nums.isEmpty() && !nums.isEmpty()) { // 确保栈中有足够的操作数
							nums.push(calculate(nums.pop(), nums.pop(), op));
						}
					}
				}

				// 根据操作符计算两个操作数的值
				private static int calculate(int a, int b, char op) {
					switch (op) {
						case '#':
							return 2 * a + 3 * b + 4; // 计算 x#y
						case '$':
							return 3 * a + b + 2; // 计算 x$y
						default:
							throw new IllegalArgumentException("Invalid operator: " + op);
					}
				}
			}